home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 June / MACPOWER-1997-06.ISO.7z / MACPOWER-1997-06.ISO / AMUG / PROGRAMMING / BSDSoundLib 1.0.1.sit / BSDSoundLib dist / BSDSoundLib ƒ / BSDSoundLib.cp < prev    next >
Text File  |  1997-01-21  |  5KB  |  221 lines

  1. /*
  2.      File:        BSDSoundLib.c
  3.  
  4.      Contains:    Sound Routines.
  5.  
  6.      Version:    Technology:    Torture Chamber v1.0
  7.                  Package:    BSDSoundLib v1.0.1
  8.  
  9.      Copyright:    ゥ 1997, BuggySoftェ Development.
  10.                  By Scott Dunbar
  11. */
  12.  
  13. #ifndef __BSDSOUNDLIB_
  14. #include "BSDSoundLib.h"
  15. #endif
  16.  
  17. #define volume(lvol, rvol) (rvol << 16L | lvol)
  18.  
  19. short            numChannels = 0, curSndLoc;
  20. Boolean            sndChanActive[kMaxSndChans], loopingActive;
  21. SndChannelPtr    sndChan[kMaxSndChans], loopingSndChan;
  22. SndCallBackUPP    soundCallBackUPP, loopingCallBackUPP;
  23.  
  24. static SoundHeaderPtr GetSoundHeader (Handle sndHandle);
  25. static pascal void SoundCallBack (SndChannelPtr chan, SndCommand cmd);
  26. SndChannelPtr InitChannel (long chanMode, SndCallBackUPP callBackProc);
  27. void DisposeChannel (SndChannelPtr chan);
  28. void DisposeLoopingChannel (void);
  29. static pascal void loopingCallBack (SndChannelPtr chan, SndCommand cmd);
  30.  
  31. void SetChanVol (short chanNum, short balance) {
  32. SndCommand    sc;
  33.  
  34.     if (sndChan[chanNum] != nil) {
  35.         if (balance < -128) balance = -128;
  36.         if (balance > 128) balance = 128;
  37.         sc.cmd = volumeCmd;
  38.         sc.param1 = 0;
  39.         sc.param2 = volume(128 - balance, 128 + balance);
  40.         SndDoImmediate(sndChan[chanNum], &sc);
  41.     }
  42. }
  43.  
  44. void BalanceSndChannels (void) {
  45. short    x;
  46.  
  47.     for (x = 0; x < numChannels; x++) 
  48.         if (sndChanActive[x] == false) SetChanVol(x, kBalanced);
  49. }
  50.  
  51. short FindFreeChannel (void) {
  52. short    x;
  53.  
  54.     for (x = 0; x < numChannels; x++) 
  55.         if (sndChanActive[x] == false) return(x);
  56.     return(-1);
  57. }
  58.  
  59. void InitSoundUtils (void) {
  60. short    x, y = 0;
  61.  
  62.     soundCallBackUPP = NewSndCallBackProc(SoundCallBack);
  63.     for (x = 0; x < kMaxSndChans; x++) {
  64.         sndChan[y] = InitChannel(initStereo, soundCallBackUPP);
  65.         if (sndChan[y] != nil) {
  66.             sndChanActive[y] = false;
  67.             numChannels++;
  68.             y++;
  69.         } else y--;
  70.     }
  71. }
  72.  
  73. void DisposeSoundUtils (void) {
  74. short    x;
  75.  
  76.     for (x = 0; x < numChannels; x++) DisposeChannel(sndChan[x]);
  77.     DisposeRoutineDescriptor(soundCallBackUPP);
  78. }
  79.  
  80. static SoundHeaderPtr GetSoundHeader (Handle sndHandle) {
  81. long    offset;
  82.  
  83.     if (GetSoundHeaderOffset((SndListHandle)sndHandle, &offset) != noErr) return nil;
  84.     else return ((SoundHeaderPtr)((Ptr)(*sndHandle) + offset));
  85. }
  86.  
  87. static pascal void SoundCallBack (SndChannelPtr chan, SndCommand cmd) {
  88.     sndChanActive[chan->userInfo] = false;
  89. }
  90.  
  91. SndChannelPtr InitChannel (long chanMode, SndCallBackUPP callBackProc) {
  92. SndChannelPtr    chan = nil;
  93.  
  94.     if (chanMode != (initChanLeft||initChanRight||initNoInterp||initNoDrop||initMono||initStereo))
  95.         chanMode = initStereo + initNoInterp;
  96.     if ((SndNewChannel(&chan, sampledSynth, chanMode, callBackProc) != noErr) || (MemError() != noErr) || (chan == nil)) 
  97.         DisposePtr((Ptr)chan);
  98.     return(chan);
  99. }
  100.  
  101. void DisposeChannel (SndChannelPtr chan) {
  102. SndCommand sc;
  103.  
  104.     if (chan != nil) {
  105.         sc.cmd = flushCmd;
  106.         sc.param1 = 0;
  107.         sc.param2 = 0;
  108.         SndDoImmediate(chan, &sc);
  109.         
  110.         sc.cmd = quietCmd;
  111.         sc.param1 = 0;
  112.         sc.param2 = 0;
  113.         SndDoImmediate(chan, &sc);
  114.         
  115.         SndDisposeChannel(chan, false);
  116.         DisposePtr((Ptr)chan);
  117.     }
  118. }
  119.  
  120. void SilenceChannel (short chanNum) {
  121. SndCommand sc;
  122.  
  123.     if (sndChan[chanNum] != nil) {
  124.         sc.cmd = flushCmd;
  125.         sc.param1 = 0;
  126.         sc.param2 = 0;
  127.         SndDoImmediate(sndChan[chanNum], &sc);
  128.         sc.cmd = quietCmd;
  129.         sc.param1 = 0;
  130.         sc.param2 = 0;
  131.         SndDoImmediate(sndChan[chanNum], &sc);
  132.         
  133.         sndChanActive[chanNum] = false;
  134.     }
  135. }
  136.  
  137. void PlaySnd (Handle snd) {
  138.     PlaySound(FindFreeChannel(), snd);
  139. }
  140.  
  141. void PlaySound (short chanNum, Handle snd) {
  142. SndCommand     sc;
  143.  
  144.     if ((sndChan[chanNum] != nil) && (snd != nil)) {
  145.         sc.cmd = bufferCmd;
  146.         sc.param1 = 0;
  147.         sc.param2 = (long)GetSoundHeader(snd);
  148.         SndDoImmediate(sndChan[chanNum], &sc);
  149.         
  150.         sndChanActive[chanNum] = true;
  151.         sndChan[chanNum]->userInfo = chanNum;
  152.         
  153.         sc.cmd = callBackCmd;
  154.         sc.param1 = 0;
  155.         sc.param2 = 0;
  156.         SndDoCommand(sndChan[chanNum], &sc, true);
  157.     }
  158. }
  159.  
  160. void InitLoopingSounds (void) {
  161.     loopingCallBackUPP = NewSndCallBackProc(loopingCallBack);
  162.     loopingSndChan = InitChannel(initStereo, loopingCallBackUPP);
  163. }
  164.  
  165. void DisposeLoopingSounds (void) {
  166.     DisposeLoopingChannel();
  167.     DisposeRoutineDescriptor(loopingCallBackUPP);
  168. }
  169.  
  170. void PlayLoopingSound (Handle snd) {
  171. SndCommand    sc;
  172.  
  173.     if ((loopingSndChan != nil) && (snd != nil)) {
  174.         loopingSndChan->userInfo = (long)GetSoundHeader(snd);
  175.         
  176.         sc.cmd = callBackCmd;
  177.         sc.param1 = 0;
  178.         sc.param2 = 0;
  179.         SndDoCommand(loopingSndChan, &sc, false);
  180.     }
  181. }
  182.  
  183. void SilenceLoopingChannel (void) {
  184. SndCommand sc;
  185.  
  186.     if (loopingSndChan != nil) {
  187.         sc.cmd = flushCmd;
  188.         sc.param1 = 0;
  189.         sc.param2 = 0;
  190.         SndDoImmediate(loopingSndChan, &sc);
  191.         
  192.         sc.cmd = quietCmd;
  193.         sc.param1 = 0;
  194.         sc.param2 = 0;
  195.         SndDoImmediate(loopingSndChan, &sc);
  196.         
  197.         loopingActive = false;
  198.     }
  199. }
  200.  
  201. void DisposeLoopingChannel (void) {
  202.     if (loopingSndChan != nil) {
  203.         SilenceLoopingChannel();
  204.         
  205.         SndDisposeChannel(loopingSndChan, false);
  206.         DisposePtr((Ptr)loopingSndChan);
  207.     }
  208. }
  209.  
  210. static pascal void loopingCallBack (SndChannelPtr chan, SndCommand cmd) {
  211. SndCommand    sc;
  212.     sc.cmd = bufferCmd;
  213.     sc.param1 = 0;
  214.     sc.param2 = chan->userInfo;
  215.     SndDoImmediate(chan, &sc);
  216.         
  217.     sc.cmd = callBackCmd;
  218.     sc.param1 = 0;
  219.     sc.param2 = 0;
  220.     SndDoCommand(chan, &sc, true);
  221. }